/*
 * send.c
 *
 *  Created on: Sep 21, 2013
 *      Author: Joseph DeLong
 */

#include <string.h>
#include <stdlib.h>
#include "defines.h"

/*
 * SEND function
 * Written by Joseph DeLong
 * parameter text:	A variable-sized character pointer (string)
 * parameter size:	An integer value representing the length of the text string
 * returns:			An integer value representing the results of text processing
 */
int send(char* text, int size) {
	int returnVal = 0; //results of processing operations will be stored here (0 means OK)
	int i; //general counter used in for() loops
	int numLines = 0; //number of lines worth of text
	int numScreens = 0; //number of screens worth of text
	int linePos = 0; //counter for current line position
	int charsOnScreen = 0; //counter for number of characters per screen
	int tokenSize = 0; //counter for measuring size of next token to be parsed
//	int lastIndex; //position of start of last token

	//process text
	for(i = 0; i < size; i++) { //iterate char by char
		if(charsOnScreen < maxScreenChars) { //if more chars can be fit on screen
			if(linePos < maxW) { //if more chars can be fit on current line
				if(numLines < (maxH - 1)) { //if more lines can be fit on screen
					if(text[i] == '\n') { //if newLine found
						numLines++; //increment lineNumber counter
						linePos = 0; //rest linePosition counter
					}
					int j; //counter for calculating next token size
					for(j = (i + linePos); j < size; j++) { //get next token size
						if(text[j] == '\n') { //if next token is newLine
							break; //return to parsing
						}
						if(text[j] == '\t') { //if next token is a TAB
							break; //return to parsing
						}
						if(text[j] != ' ') { //if next char is NOT a whitespace
							tokenSize++; //keep counting size of this token
						}
						if(tokenSize >= maxW) { //token too big for one line
							insert_substring(text,"\n",j); //split token at this index
							numLines++; //increment number of lines
							tokenSize = 0; //reset counter
							//numLines++; //the [i] loop should catch this
							size++; //add 1 to size b/c of inserting '\n'
							linePos = 0; //reset counter
							break; //return to parsing
						}
					}
					if( (tokenSize + linePos) >= maxW) { //token too big to fit on line
						tokenSize = 0; //reset counter
						text[i] = '\n'; //change whitespace to newLine at current index
						numLines++; //increment number of lines
						linePos = 0; //reset counter
					}
				}
				else { //reached max number of lines allowed on screen
					insert_substring(text, continueMsg, i); //insert line 25
					size += sizeof(continueMsg); //increase size of text by size of line 25
					numLines++; //increment line counter
					numScreens++; //increment screen counter
					charsOnScreen = 0; //reset counter
					linePos = 0; //reset counter
				}
			}
			linePos++; //count position in current line
		}
		else{ //reached max number of characters allowed on screen
			insert_substring(text, continueMsg, i); //insert line 25
			size += sizeof(continueMsg); //increment text size by size of line 25
			numLines++; //increment line counter
			numScreens++; //increment screen counter
			charsOnScreen = 0; //reset counter
			linePos = 0; //reset counter
		}
		charsOnScreen++; //keep counting number of chars on this screen
	}

//RESUME CODING HERE...9/28/13

	//OUTPUT parsing
	if(numLines <= 24) { //don't bother splitting text up any further
		sys_req(2, 1, text, &size); //output text to screen
		returnVal = 0; //indicate good output sent
	}
	else { //begin splitting text chunks into SCREENS
		for (i = 0; i < numLines; ++i) {
			if((numLines + 1) % 24 > 0) { //if a full screen's worth of text is indicated
				sys_req(2, 1, NULL, NULL); //FIX THIS
			}
			//split up lines into SCREENS using maxH (defines.h) <<remember to leave line 25 for the "PRESS ENTER TO CONTINUE" prompt, if necessary
		}
		//count total SCREENS (numBreaks)
		char *output[numScreens]; //storage for one terminal screen's worth of display text
		for (i = 0; i < numScreens; ++i) {
			output[i] = ((char *) sys_alloc_mem(sizeof(char) * (maxW * maxH))); //allocate memory for each SCREEN space
		}

		//INSERT TEXT INTO SCREENS FOR OUTPUT

		//printing of output
		for (i = 0; i < numScreens; ++i) {//iterate through each SCREEN
			sys_req(2, 1, output[i], sizeof(output[i])); //WRITE(2) to TERMINAL(1)
		}
		for (i = 0; i < numScreens; ++i) {
			sys_free_mem(output[i]); //clean up now-defunct memory chunk
		}
		sys_free_mem(output); //clean up now-defunct memory chunk
		returnVal = 0; //indicate good output sent
	}
	return returnVal;
}

/*
 * INSERT_SUBSTRING function
 * found online at:
 * 	http://www.programmingsimplified.com/c/source-code/c-program-insert-substring-into-string
 */
void insert_substring(char *a, char *b, int position)
{
	char *f, *e;
	int length;
	length = strlen(a);
	f = substring(a, 1, position - 1 );
	e = substring(a, position, length - position + 1);
	strcpy(a, "");
	strcat(a, f);
	sys_free_mem(f);
	strcat(a, b);
	strcat(a, e);
	sys_free_mem(e);
}

/*
 * SUBSTRING function
 * found online at:
 * 	http://www.programmingsimplified.com/c/source-code/c-program-insert-substring-into-string
 */
char *substring(char *string, int position, int length)
{
	char *pointer;
	int c;
	pointer = sys_alloc_mem(length + 1);
	if(pointer == NULL)
		exit(EXIT_FAILURE); //CHANGE THIS TO RETURN VALUE INSTEAD OF HARD EXIT
	for(c = 0 ; c < length ; c++)
		*(pointer + c) = *((string + position - 1) + c);
	*(pointer + c) = '\0';
	return pointer;
}
